﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using utility;
using AForge;
using AForge.Imaging.Filters;
using System.Windows.Ink;

namespace Preprocess
{
    public class ImageResize
    {
        enum Dimensions
        {
            Width,
            Height
        }
        enum AnchorPosition
        {
            Top,
            Center,
            Bottom,
            Left,
            Right
        }

        public static System.Drawing.Image FixedSize(System.Drawing.Image imgPhoto, int Width, int Height)
        {
            int sourceWidth = imgPhoto.Width;
            int sourceHeight = imgPhoto.Height;
            int sourceX = 0;
            int sourceY = 0;
            int destX = 0;
            int destY = 0;

            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;

            nPercentW = ((float)Width / (float)sourceWidth);
            nPercentH = ((float)Height / (float)sourceHeight);

            //if we have to pad the height pad both the top and the bottom
            //with the difference between the scaled height and the desired height
            if (nPercentH < nPercentW)
            {
                nPercent = nPercentH;
                destX = (int)((Width - (sourceWidth * nPercent)) / 2);
            }
            else
            {
                nPercent = nPercentW;
                destY = (int)((Height - (sourceHeight * nPercent)) / 2);
            }

            int destWidth = (int)(sourceWidth * nPercent);
            int destHeight = (int)(sourceHeight * nPercent);

            System.Drawing.Bitmap bmPhoto = new System.Drawing.Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

            System.Drawing.Graphics grPhoto = System.Drawing.Graphics.FromImage(bmPhoto);
            grPhoto.Clear(System.Drawing.Color.White);
            grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            grPhoto.DrawImage(imgPhoto,
                new System.Drawing.Rectangle(destX, destY, destWidth, destHeight),
                new System.Drawing.Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
                System.Drawing.GraphicsUnit.Pixel);

            grPhoto.Dispose();
            return bmPhoto;
        }
        
    }
    /// <summary>
    /// feature extraction
    ///                                            --------------------------------
    /// base64 - > strokes collection -> bitmap -> |resize -> grayscale -> thresold|-> matrix -> feature vector 
    ///                                            --------------------------------
    /// </summary>
    public class Process
    {
        
        public static readonly System.Windows.Size size = new System.Windows.Size(50d, 50d);
        public static System.Drawing.Bitmap ApplyFilter(IFilter filter, System.Drawing.Bitmap source)
        {

            // apply filter
            return filter.Apply(source);
            // display filtered image
        }
        private System.Drawing.Bitmap grayscaleFilters(System.Drawing.Bitmap source)
        {
            return ApplyFilter(Grayscale.CommonAlgorithms.BT709, source);
        }
        public static System.Drawing.Bitmap thresholdFilters(System.Drawing.Bitmap source)
        {
            // save original image


            // get grayscale image
            source = Grayscale.CommonAlgorithms.RMY.Apply(source);
            // apply threshold filter
            return ApplyFilter(new Threshold(200), source);

        }
        /// <summary>
        /// resize image to specified size
        /// </summary>
        /// <param name="imgToResize"> image to resize</param>
        /// <param name="size"> specified size </param>
        /// <returns>target bimap image </returns>
        /// 
        public static System.Drawing.Image fixedSizeImage(System.Drawing.Image imgToResize)
        {
            return ImageResize.FixedSize(imgToResize , (int)size.Width , (int) size.Height);
        }
        public static System.Drawing.Bitmap resizeImage(System.Drawing.Bitmap imgToResize)
        {
            int sourceWidth = imgToResize.Width;
            int sourceHeight = imgToResize.Height;

            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;

            nPercentW = ((float)size.Width / (float)sourceWidth);
            nPercentH = ((float)size.Height / (float)sourceHeight);

            if (nPercentH < nPercentW)
                nPercent = nPercentH;
            else
                nPercent = nPercentW;

            int destWidth = (int)(sourceWidth * nPercent);
            int destHeight = (int)(sourceHeight * nPercent);

            System.Drawing.Bitmap b = new System.Drawing.Bitmap(destWidth, destHeight);
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage((System.Drawing.Image)b);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
            g.Dispose();

            return b;
        }
        public static System.Drawing.Bitmap inVerse(ref System.Drawing.Bitmap bm)
        {
            for (int i = 0; i < bm.Height; i++)
                for (int j = 0; j < bm.Width; j++)
                {
                    if (bm.GetPixel(j, i).R == 255)
                        bm.SetPixel(j, i, System.Drawing.Color.Black);
                    else
                        bm.SetPixel(j, i, System.Drawing.Color.White);
                }
            return bm;
        }
        public static double[] vExtraction(string base64)
        {
            // base64 -> bitmap
            System.Drawing.Bitmap original = tools.Base64ToGDIBitmap(base64);
            System.Drawing.Bitmap rImage = resizeImage(original);
            rImage = thresholdFilters(rImage);
            
            return tools.GDIBitmapToVector(rImage);
        }
        public static double[,] mExtraction(string base64)
        {
            System.Drawing.Bitmap original = tools.Base64ToGDIBitmap(base64);
            System.Drawing.Bitmap rImage = resizeImage(original);
            rImage = thresholdFilters(rImage);
            return tools.GDIBitmapToMatrix(rImage);
        }
        
        public static double[,] mExtraction(StrokeCollection sc)
        {
            System.Drawing.Bitmap reImage = resizeImage(tools.StrokesToGDIBitmap(sc));
            reImage = thresholdFilters(reImage);
            return tools.GDIBitmapToMatrix(reImage);
        }
        public static double[] vExtraction(StrokeCollection sc)
        {
            System.Drawing.Bitmap reImage = resizeImage(tools.StrokesToGDIBitmap(sc));
            reImage = thresholdFilters(reImage);
            return tools.GDIBitmapToVector(reImage);
        }
        
    }
}
